package cn.com.mdx.sort.heapsort.eventdrivensimulation;

import edu.princeton.cs.algs4.StdDraw;

/**
 * <p>
 *
 * @author ：huangy
 * @date ：Created in 2020/10/20 11:35 上午
 */
public class Particle {
    /**
     * x,y轴的位置
     */
    private double rx, ry;
    /**
     * x,y方向的速度
     */
    private double vx, vy;
    /**
     * 粒子的半径
     */
    private final double radius = 0.05;
    /**
     * 混乱度
     */
    private final double mass = 0.01;
    /**
     * 碰撞次数
     */
    private int count;

    public Particle() {

    }

    /**
     * @param dt 时间差值
     * @return void
     * @Author huangy
     * @description //TODO
     * @date 5:01 下午 2020/10/20
     **/
    public void move(double dt) {
        if (rx + vx * dt < radius || rx + vx * dt > 1.0 - radius) vx = -vx;
        if (ry + vy * dt < radius || rx + vy * dt > 1.0 - radius) vy = -vy;
        rx = rx + vx * dt;
        ry = ry + vy * dt;
    }

    public void draw() {
        StdDraw.filledCircle(rx, ry, radius);
    }

    /**
     * @param that 另一个粒子
     * @return double
     * @Author huangy
     * @description //TODO 两个粒子碰撞事件预测
     * @date 9:45 上午 2020/10/22
     **/
    public double timeToHit(Particle that) {
        if (this == that) return Double.POSITIVE_INFINITY;
        double dx = that.rx - this.rx, dy = that.ry - this.ry;
        double dvx = that.vx - this.vx, dvy = that.vy - this.vy;
        double dvdr = dx * dvx + dy * dvy;
        if (dvdr > 0) return Double.POSITIVE_INFINITY;
        double dvdv = dvx * dvx + dvy * dvy;
        double drdr = dx * dx + dy * dy;
        double sigma = this.radius + that.radius;
        double d = (dvdr * dvdr) - dvdv * (drdr - sigma * sigma);
        if (d < 0) return Double.POSITIVE_INFINITY;
        return -(dvdr + Math.sqrt(d)) / dvdv;
    }

    public double timeToHitVerticalWall() {
        return 0.0d;
    }

    public double timeToHitHorizontalWall() {
        return 0.0d;
    }

    /**
     * @param that 另一个粒子
     * @return void
     * @Author huangy
     * @description //TODO 粒子反弹
     * @date 9:47 上午 2020/10/22
     **/
    public void bounceOff(Particle that) {
        double dx = that.rx - this.rx, dy = that.ry - this.ry;
        double dvx = that.vx - this.vx, dvy = that.vy - this.vy;
        double dvdr = dx * dvx + dy * dvy;
        double dist = this.radius + that.radius;
        double J = 2 * this.mass * this.mass * dvdr / ((this.mass + this.mass) * dist);
        double Jx = J * dx / dist;
        double Jy = J * dy / dist;
        this.vx += Jx / this.mass;
        this.vy += Jy / this.mass;
        that.vx -= Jx / that.mass;
        that.vy -= Jy / that.mass;
        this.count++;
        that.count++;
    }

    public void bounceOffVerticalWall() {

    }

    public void bounceOffHorizontalWall() {
    }

}
